#!/usr/bin/env python
# -*-*- encoding: utf-8 -*-*-
#
#
# Copyright 2007-2008 Håvard Gulldahl
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""A desktop client for PicasaWeb services."""

__author__ = u'havard@gulldahl.no (Håvard Gulldahl)'


import sys, os, mimetypes
from PyQt4 import QtGui, QtCore

import gdata.photos, gdata.photos.service

class PicasaTreeWidget(QtGui.QTreeView):
  def dragEnterEvent(self, event):
    print "dragenter"
    #print [unicode(s) for s in event.mimeData().formats()]

    if event.source() == self:
      event.ignore()
      return

    if self.validDndFormat(event.mimeData()) and self.validDndTarget(event):
      event.setDropAction(QtCore.Qt.CopyAction)
      event.accept()
    else:
      event.ignore()


  def dragMoveEvent(self, event):
    print "dragmove"
    if self.validDndFormat(event.mimeData()) and self.validDndTarget(event):
      event.setDropAction(QtCore.Qt.CopyAction)
      event.accept()
    else:
      event.ignore()

  def dropEvent(self, event):
    print "drop"
    if not (self.validDndFormat(event.mimeData()) and self.validDndTarget(event)):
      event.ignore()
    else:
      item = self.indexAt(event.pos()).internalPointer()
      print "dropped on", type(item), type(item.entry)
      if isinstance(item.entry, gdata.photos.AlbumEntry):
        albumItem = item
      elif isinstance(item.entry, gdata.photos.PhotoEntry):
        albumItem = item.parent
      else:
        event.ignore() #not valid drop target
        return

      print "album: ", albumItem.entry.name.text
      event.setDropAction(QtCore.Qt.CopyAction)
      event.accept()
      files = [ unicode(u.toString()).strip() for u in event.mimeData().urls() ]
      for f in files:
        if f.startswith('file://'):
          f = f[len('file://'):] # remove file pseudo-scheme
        if len(f) == 0:
          continue
        format = mimetypes.guess_type(f, strict=False)[0]
        if format is None: # couldn't guess file type, maybe no file extension?
          if os.path.splitext(f)[1] != '': #no, there is a file extension, so it must be
            continue                       #unknown to python. anyway, we don't support it
          else:
            # let the server determine whether the file is valid or not
            pass
        elif format.split('/')[1] not in gdata.photos.service.SUPPORTED_UPLOAD_TYPES:
          print "invalid mimetype:", format, format.split('/')[1]
          continue
        self.emit(QtCore.SIGNAL('insertPhoto(PyQt_PyObject,PyQt_PyObject)'), albumItem, f)

  def validDndFormat(self, mimedata):
    files = [ unicode(u.toString()).strip() for u in mimedata.urls() ]
    print files
    for f in files:
      if not len(f): continue # empty string
      if f.lower().startswith('file://'): f = f[len('file://'):]
      if not os.path.exists(f):
        print "does not exist:", f
        return False # file does not exist (or is not accessible to us, e.g. trash:/)
      if not os.path.splitext(f)[1]: continue # no filename extension (let the photo server worry about the file type)
      guessFormat = mimetypes.guess_type(f, strict=False)[0]
      print f, "found format: ", guessFormat
      if guessFormat.split('/')[1] not in gdata.photos.service.SUPPORTED_UPLOAD_TYPES:
        print "not accepting ", guessFormat
        return False
    return True

  def validDndTarget(self, event, valid=gdata.photos.AlbumEntry):
    try:
      item = self.indexAt(event.pos())
      print "dnd target", type(item)
    except Exception, e:
      print e
      return False
    try:
      entry = item.internalPointer().parent.entry # is it dropped on a PhotoEntry (expanded album)?
    except AttributeError:
      try:
        entry = item.internalPointer().entry # is it dropped on a AlbumEntry (album)
      except AttributeError:
        return False
      except Exception, e:
        print e
        return False
    except Exception, e:
      print e
      return False
    print "Target: ",type(entry)
    return isinstance(entry, valid)

